package DEEPERsource.DEEPERsource.source.parser;

import java.util.Collection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import edu.stanford.nlp.ling.Sentence;
import edu.stanford.nlp.ling.TaggedWord;
import edu.stanford.nlp.trees.Tree;
import edu.stanford.nlp.trees.TypedDependency;

import jung.entities.Graph;
import parser.stanfordparser.StanfordParserWrapper;
import parser.stanfordparser.JUNGadapter.StanfordGraphFactory;

/**
 * Implementation of Parser interface for the Stanford Parser
 * @author tfayruzo
 *
 */
public class StanfordParser implements Parser {
	
	public static Log _log = LogFactory.getLog(StanfordParser.class);

	//parser wrapper is isolated in separate class just for the sake of
	//keeping parser code separately. Probably put it right here?
	private StanfordParserWrapper parser = null;
	
	//GraphFactory isolated to separate class to keep JUNG code
	//as much independent as possible
	private StanfordGraphFactory factory = null;
	
	/**
	 * Acceptable arguments
	 * -maxLength int
	 * -dependencyType dependencies|collapsedDependencies|typedDependenciesCCprocessed
	 */
	public void init(String... args) {
		int maxLength = 0;
		String dependencyType = "";
		for(int i = 0, size = args.length; i<size;i++){
			if(args[i].equals("-maxLength")){
				maxLength = Integer.parseInt(args[++i]);
			}else if(args[i].equals("-dependencyType")){
				dependencyType = args[++i];
			}
		}
		parser = new StanfordParserWrapper(maxLength, dependencyType);
		factory = new StanfordGraphFactory();
	}
	
	public void parse(String sentence) throws IllegalStateException, Exception{
		if(parser==null){
			throw new IllegalStateException("Parser should be initialized before calling parse() method.");
		}
		try{
			parser.getParse(sentence);
		}catch(UnsupportedOperationException e){
			_log.error(sentence);
			throw new Exception(sentence+" Nested exception message: "+e.getMessage());
		}
	}

	public Graph getDependencyTree() throws IllegalStateException{
		Collection<TypedDependency> deps = parser.getTypedDependencies();
		if(deps == null){
			throw new IllegalStateException("No parse() method was executed. Dependency tree not yet exists.");
		}
		//getting dependency graph
		Graph g = factory.getDepGraph(deps);
		//adding POS information
		g = factory.addPOS(g, getStructuredSentence());
		return g;
	}

	public Graph getParseTree() throws IllegalStateException{
		Tree tree = parser.getParseTree();
		if(tree == null){
			throw new IllegalStateException("No parse() method was executed. Parse tree not yet exists.");
		}
		return factory.getParseGraph(tree);
	}

	public StructuredSentence getStructuredSentence() throws IllegalStateException{
		Sentence<TaggedWord> sent = parser.getSentence();
		if(sent == null){
			throw new IllegalStateException("No parse() method was executed. Structured sentence not yet exists.");
		}
		return factory.getSentence(sent);
	}
}
